/**
 * ReportGear 2010
 */
package com.reportgear.report.view.grid.selection;

import java.util.ArrayList;
import java.util.List;

import net.abbp.report.model.Cell;

/**
 * Grid选择模型，支持多重选择
 * 
 * @version 1.0 2011-3-14
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 * 
 */
public class GridSelection {
    /**
     * 单元格类型
     * 
     * @version 1.0 2011-3-14
     * @author <a herf="lexloo@gmail.com">lexloo</a>
     * @since ANNCSR 2.0
     * 
     */
    public enum Type {
        /**
         * 单元格对象
         */
        CELL,
        /**
         * 浮动对象
         */
        FLOAT
    };

    // 所有选择矩形
    private final List<Selection> celSelectionList = new ArrayList<Selection>();
    // 编辑矩形
    private final Selection editSelection = new Selection(0, 0);
    // 浮动对象列表
    private final List<String> floatNameList = new ArrayList<String>();
    // 选择类型
    private Type type = Type.CELL;

    public GridSelection() {
        this.celSelectionList.add(new Selection(0, 0));
    }

    /**
     * 增加选择域
     * 
     * @param selection
     *            选择域
     */
    public void addCellSelection(Selection selection) {
        if (this.celSelectionList.indexOf(selection) != -1) {
            this.celSelectionList.add(selection);
        }
    }

    /**
     * 选择浮动对象
     * 
     * @param name
     *            浮动对象名称
     */
    public void addFloatName(String name) {
        this.floatNameList.add(name);
    }

    /**
     * 清空所有选择域
     */
    public void clearAllCellSelections() {
        this.celSelectionList.clear();
    }

    /**
     * 清空浮动对象
     */
    public void clearAllFloatName() {
        this.floatNameList.clear();
    }

    /**
     * 检测是否包含浮动对象
     * 
     * @param name
     *            浮动对象名称
     * @return 是否包含
     */
    public boolean containFloatName(String name) {
        return this.floatNameList.contains(name);
    }

    /**
     * 判断是否包含指定列、行单元格
     * 
     * @param column
     *            列
     * @param row
     *            行
     * @return 包含则为true，否则false
     */
    public boolean containsCell(int column, int row) {
        for (final Selection sel : this.celSelectionList) {
            if (sel.contains(column, row)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取指定选择域
     * 
     * @param index
     *            索引
     * @return 选择域
     */
    public Selection getCellSelection(int index) {
        return this.celSelectionList.get(index);
    }

    /**
     * @return 选择域数量
     */
    public int getCellSelectionCount() {
        return this.celSelectionList.size();
    }

    /**
     * @return 所有选择域
     */
    public List<Selection> getCellSelectionList() {
        return this.celSelectionList;
    }

    /**
     * @return 选择矩形
     */
    public Selection getEditSelection() {
        return this.editSelection;
    }

    /**
     * @return 第一个选择域
     */
    public Selection getFirstCellSelection() {
        return this.celSelectionList.get(0);
    }

    /**
     * 获取指定索引的浮动对象
     * 
     * @param index
     *            索引
     * @return 浮动对象名称
     */
    public String getFloatName(int index) {
        return this.floatNameList.get(index);
    }

    /**
     * @return 浮动对象数量
     */
    public int getFloatNameCount() {
        return this.floatNameList.size();
    }

    /**
     * @return 最后一个选择域
     */
    public Selection getLastCellSelection() {
        return this.celSelectionList.get(this.celSelectionList.size() - 1);
    }

    /**
     * 获取最后一个浮动对象的名称
     * 
     * @return 浮动对象名称
     */
    public String getLastFloatName() {
        return this.getFloatName(this.getFloatNameCount() - 1);
    }

    /**
     * @return 选择类型
     */
    public Type getType() {
        return this.type;
    }

    /**
     * 移除浮动对象
     * 
     * @param name
     *            浮动对象名称
     */
    public void removeFloatName(String name) {
        this.floatNameList.remove(name);
    }

    /**
     * 通过单元格设置编辑矩形范围
     * 
     * @param cell
     */
    public void setEditBounds(Cell cell) {
        this.setEditBounds(cell.getColumn(), cell.getRow(), cell.getColumnSpan(), cell.getRowSpan());
    }

    /**
     * 通过行列及跨度设置编辑矩形范围
     * 
     * @param column
     *            列
     * @param row
     *            行
     * @param columnSpan
     *            列跨度
     * @param rowSpan
     *            行跨度
     */
    public void setEditBounds(int column, int row, int columnSpan, int rowSpan) {
        this.editSelection.setBounds(column, row, columnSpan, rowSpan);
    }

    /**
     * 设置唯一选择矩形访问
     * 
     * @param cell
     *            单元格
     */
    public void setOnlySelection(Cell cell) {
        this.setOnlySelection(cell.getColumn(), cell.getRow(), cell.getColumnSpan(), cell.getRowSpan());
    }

    /**
     * 设置唯一选择矩形访问
     * 
     * @param column
     *            列
     * @param row
     *            行
     * @param columnSpan
     *            列跨度
     * @param rowSpan
     *            行跨度
     */
    public void setOnlySelection(int column, int row, int columnSpan, int rowSpan) {
        Selection tmpSelection = null;

        if (this.celSelectionList.size() > 0) {
            tmpSelection = this.celSelectionList.get(0);
        } else {
            tmpSelection = new Selection();
        }

        this.celSelectionList.clear();
        tmpSelection.setBounds(column, row, columnSpan, rowSpan);
        this.celSelectionList.add(tmpSelection);
    }

    /**
     * 设置选择类型
     * 
     * @param type
     *            选择类型
     */
    public void setType(Type type) {
        this.type = type;
        if (this.type == Type.FLOAT) {
            this.setEditBounds(0, 0, 1, 1);
            this.clearAllCellSelections();
        } else {
            this.clearAllFloatName();
        }
    }
}
